//
//  XLUploadFileTool.m
//  industry
//
//  Created by xl on 2020/12/1.
//  Copyright © 2020 Haier. All rights reserved.
//

#import "XLUploadFileTool.h"
#import "XLDateTool.h"
#import <AliyunOSSiOS/OSSService.h>
#import <AVKit/AVKit.h> // 1. 导入头文件  iOS 9 新增
#import "XLDateTool.h"

//暂时定上传文件大小
#define XLFilesUploadSize 200*1024*1024
#define XLFilesPerSize 1024*1024
#define XLFilesMinSize 102400
#define XLBucketName @"hfmpaas"
#define XLEndPoint @"oss-accelerate.aliyuncs.com"

@interface XLUploadFileTool ()

@property (nonatomic, weak)  id<OSSCredentialProvider> credential;
@property (nonatomic, strong) OSSClient *client;
@property (nonatomic, strong) NSNumber *expiration;//endPoint和Key的过期时间
@property (nonatomic, strong) NSDictionary *ossInfoDic;

@end
@implementation XLUploadFileTool

+ (instancetype)sharedInstance {
    static XLUploadFileTool *instance;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        instance = [XLUploadFileTool new];
    });
    return instance;
}

- (instancetype)init {
    self = [super init];
    if (self) {
        //请求服务器获取最新参数
//        XLHttpRequest *request = [[XLHttpRequest alloc] init];
//        NSMutableDictionary *params = [NSMutableDictionary dictionary];
//        if (!ISEmptyString(XL_UserInfoData.securityToken)) {
//            [params setValue:XL_UserInfoData.securityToken forKey:@"securityToken"];
//        }
//        [request requestWithMethod:XLHttpMedthTypeGET url:XLFetchOSSTokenUrl params:params isExtraParams:NO successBlock:^(NSDictionary *dict) {
//             [[XLUploadFileTool sharedInstance] initClientWithServerDic:dict];
//        } failBlock:^(XLServerRequestsStatus status, XLNetworkReachabilityStatus reachability, NSError *error, NSDictionary *dict) {
//
//        }];
    }
    return self;
}
/** 检测oss的key是否在有消息内 **/
- (BOOL)checkExpirationTime {
    BOOL needRequest = NO;
    if (ISEmptyNumber(_expiration)) {
        needRequest = YES;
    } else if ([XLDateTool currentTimeInMilliseconds] - (_expiration.longLongValue - 1000*60*60*24) > 0) {
        //当前时间大于过期时间的前一分钟
        return YES;
    }
    return needRequest;
}

/** 初始化oss client **/
- (void)initClientWithServerDic:(NSDictionary *)dic {
    NSString *accessKeyId = [dic objectForKey:@"keyId"];
    NSString *accessKeySecret = [dic objectForKey:@"keySecret"];
    NSString *securityToken = [dic objectForKey:@"securityToken"];
    self.ossInfoDic = dic;
    if (ISEmptyString(accessKeyId) || ISEmptyString(accessKeySecret) || ISEmptyString(securityToken)) {
        return;
    }
    
    //存储新的token
    XL_UserInfoData.securityToken = securityToken;
    [[XLUserData sharedXLUserData] saveCurrentUserInfo:XL_UserInfoData];
    
    
    self.expiration = [dic objectForKey:@"expiration"];
    id<OSSCredentialProvider> credential = [[OSSStsTokenCredentialProvider alloc] initWithAccessKeyId:accessKeyId secretKeyId:accessKeySecret securityToken:securityToken];
    OSSClientConfiguration * conf = [OSSClientConfiguration new];
    conf.maxRetryCount = 3; // 网络请求遇到异常失败后的重试次数
    conf.timeoutIntervalForRequest = 60; // 网络请求的超时时间
    conf.timeoutIntervalForResource = 24 * 60 * 60; // 允许资源传输的最长时间
    self.client = [[OSSClient alloc] initWithEndpoint:XLEndPoint credentialProvider:credential clientConfiguration:conf];
}

/** 图片或者上传 */
- (void)uploadImagesData:(NSArray *)imagesData
            successBlock:(UploadDatasSuccessBlock)successBlock
               failBlock:(UploadDatasFailBlock)failBlock {
    NSMutableArray *temArr = [NSMutableArray array];
    for (int i = 0; i < imagesData.count; i ++) {
        id temData = imagesData[i];
        NSString *filePath = [NSString stringWithFormat:@"%@picture",SSOFilePath];
        NSString *suffixName = @".jpeg";
        NSString *fileNamePath = [NSString stringWithFormat:@"%@/%@_%d%@",filePath,[XLDateTool getCurrentTimeFormatter:@"yyyyMMddHHmmssSSS"],(arc4random()%10000),suffixName];
        OSSPutObjectRequest *put = [OSSPutObjectRequest new];
        put.bucketName = XLBucketName;
        put.objectKey = fileNamePath;
        put.uploadingData = temData;
        put.uploadProgress = ^(int64_t bytesSent, int64_t totalBytesSent, int64_t totalBytesExpectedToSend) {
            XLLog(@"%lld, %lld, %lld", bytesSent, totalBytesSent, totalBytesExpectedToSend);
        };
        OSSTask *putTask = [_client putObject:put];
        [putTask continueWithBlock:^id _Nullable(OSSTask * _Nonnull task) {
            if (!task.error) {
                [temArr addObject:put.objectKey];
                if (i == imagesData.count - 1) {
                    if (imagesData.count == temArr.count) {
                        successBlock([self fetchSuccessBlockResult:temArr]);
                    } else {
                        failBlock(task.error, XLNetworkReachabilityStatusUnkonw);
                    }
                }

            } else {
                failBlock(task.error, XLNetworkReachabilityStatusUnkonw);
            }
            return nil;
        }];
        [putTask waitUntilFinished];

    }
}

/** 视频缩略图上传 */
- (void)uploadThumbnailData:(NSData *)imagesData
            successBlock:(UploadDatasSuccessBlock)successBlock
               failBlock:(UploadDatasFailBlock)failBlock{
        id temData = imagesData;
        NSString *filePath = [NSString stringWithFormat:@"%@thumbnail",SSOFilePath];
        NSString *suffixName = @".jpeg";
        NSString *fileNamePath = [NSString stringWithFormat:@"%@/%@_%d%@",filePath,[XLDateTool getCurrentTimeFormatter:@"yyyyMMddHHmmssSSS"],(arc4random()%10000),suffixName];
        OSSPutObjectRequest *put = [OSSPutObjectRequest new];
        put.bucketName = XLBucketName;
        put.objectKey = fileNamePath;
        put.uploadingData = temData;
        put.uploadProgress = ^(int64_t bytesSent, int64_t totalBytesSent, int64_t totalBytesExpectedToSend) {
            XLLog(@"%lld, %lld, %lld", bytesSent, totalBytesSent, totalBytesExpectedToSend);
        };
        OSSTask *putTask = [_client putObject:put];
        [putTask continueWithBlock:^id _Nullable(OSSTask * _Nonnull task) {
            if (!task.error) {
                NSDictionary * dic = [self fetchSuccessBlockResult:@[put.objectKey]];
                [dic setValue:fileNamePath forKey:@"filePath"];
                successBlock(dic);
                    }else {
                failBlock(task.error, XLNetworkReachabilityStatusUnkonw);
            }
            return nil;
        }];
        [putTask waitUntilFinished];
    
}

/** 头像上传 */
- (void)uploadAvaterData:(NSData *)imagesData
            successBlock:(UploadDatasSuccessBlock)successBlock
               failBlock:(UploadDatasFailBlock)failBlock{
        id temData = imagesData;
        NSString *filePath = [NSString stringWithFormat:@"%@avatar",SSOFilePath];
        NSString *suffixName = @".jpeg";
        NSString *fileNamePath = [NSString stringWithFormat:@"%@/%@_%d%@",filePath,[XLDateTool getCurrentTimeFormatter:@"yyyyMMddHHmmssSSS"],(arc4random()%10000),suffixName];
        OSSPutObjectRequest *put = [OSSPutObjectRequest new];
        put.bucketName = XLBucketName;
        put.objectKey = fileNamePath;
        put.uploadingData = temData;
        put.uploadProgress = ^(int64_t bytesSent, int64_t totalBytesSent, int64_t totalBytesExpectedToSend) {
            XLLog(@"%lld, %lld, %lld", bytesSent, totalBytesSent, totalBytesExpectedToSend);
        };
        OSSTask *putTask = [_client putObject:put];
        [putTask continueWithBlock:^id _Nullable(OSSTask * _Nonnull task) {
            if (!task.error) {
                NSDictionary * dic = [self fetchSuccessBlockResult:@[put.objectKey]];
                [dic setValue:fileNamePath forKey:@"filePath"];
                successBlock(dic);
                    }else {
                failBlock(task.error, XLNetworkReachabilityStatusUnkonw);
            }
            return nil;
        }];
        [putTask waitUntilFinished];
    
}

/// 返回资源签名
/// @param filePath 路径信息
-(NSString * )presignConstrainwithObjectKey:(NSString *)filePath{
    if (!filePath) return nil;
    OSSTask * task = [_client presignConstrainURLWithBucketName:XLBucketName withObjectKey:filePath withExpirationInterval:30 * 60];

    if (!task.error) {
        return task.result;
    } else {
        NSLog(@"sign url error: %@", task.error);
        return nil;
    }
    
}


- (void)uploadVideoDataPathUrl:(NSURL *)pathUrl
                  successBlock:(UploadDatasSuccessBlock)successBlock
                     failBlock:(UploadDatasFailBlock)failBlock {
    if ([pathUrl.absoluteString hasSuffix:@".MOV"]) {//系统视频格式
        [self compressVideoAccroding:pathUrl successBlock:^(NSString *newPath) {
            if (ISEmptyString(newPath)) {
                NSError *error = nil;
                //移除缓存文件
                [self isDeleteManageFilesPath:newPath];
                //回调失败结果
                failBlock(error, XLNetworkReachabilityStatusUnkonw);
                return;
            }
            
            //压缩之后的文件的大小
            NSData *temData = [NSData dataWithContentsOfURL:[NSURL fileURLWithPath:newPath]];
            //文件夹名称
            NSString *filePath = [NSString stringWithFormat:@"%@video",SSOFilePath];
            //文件类型
            NSString *suffixName = @".mp4";//后缀名
            
            if (temData.length <= XLFilesMinSize) {//小于100KB的采用简单上传
                NSString *fileNamePath = [NSString stringWithFormat:@"%@/%@_%d%@",filePath,[XLDateTool getCurrentTimeFormatter:@"yyyyMMddHHmmssSSS"],(arc4random()%10000),suffixName];
                OSSPutObjectRequest *put = [OSSPutObjectRequest new];
                put.bucketName = XLBucketName;
                put.objectKey = fileNamePath;
                put.uploadingData = temData;
                put.uploadProgress = ^(int64_t bytesSent, int64_t totalBytesSent, int64_t totalBytesExpectedToSend) {
                    XLLog(@"%lld, %lld, %lld", bytesSent, totalBytesSent, totalBytesExpectedToSend);
                };
                OSSTask *putTask = [self->_client putObject:put];
                [putTask continueWithBlock:^id _Nullable(OSSTask * _Nonnull task) {
                    if (!task.error) {
                        //删除缓存文件
                        [self isDeleteManageFilesPath:newPath];
                        successBlock([self fetchSuccessBlockResult:@[put.objectKey]]);
                    } else {
                        //删除缓存文件
                        [self isDeleteManageFilesPath:newPath];
                        failBlock(task.error, XLNetworkReachabilityStatusUnkonw);
                    }
                    return nil;
                }];
                [putTask waitUntilFinished];
            } else {//采用分片上传
                dispatch_async(dispatch_get_global_queue(0, 0), ^{
                     __block NSString * uploadId = nil;
                     __block NSMutableArray * partInfos = [NSMutableArray new];
                     //拼接路径
                     NSString *fileNamePath = [NSString stringWithFormat:@"%@/%@_%d%@",filePath,[XLDateTool getCurrentTimeFormatter:@"yyyyMMddHHmmssSSS"],(arc4random()%10000),suffixName];
                     
                     // OSSInitMultipartUploadRequest用于指定上传文件的名称以及上传文件所属的存储空间的名称。
                     OSSInitMultipartUploadRequest * init = [OSSInitMultipartUploadRequest new];
                     init.bucketName = XLBucketName;
                     init.objectKey = fileNamePath;
                     // init.contentType = @"application/octet-stream";
                     // multipartUploadInit返回的结果中包含UploadId，UploadId是分片上传的唯一标识。
                     OSSTask * initTask = [self->_client multipartUploadInit:init];
                     [initTask waitUntilFinished];
                     if (!initTask.error) {
                         OSSInitMultipartUploadResult * result = initTask.result;
                         uploadId = result.uploadId;
                     } else {
                         NSLog(@"multipart upload failed, error: %@", initTask.error);
                         //移除缓存文件
                         [self isDeleteManageFilesPath:newPath];
                         //回调失败结果
                         dispatch_async(dispatch_get_main_queue(), ^{
                             failBlock(initTask.error, XLNetworkReachabilityStatusUnkonw);
                         });
                         return;
                     }
                     // 设置分片大小。
                     uint64_t offset = XLFilesPerSize;
                     // 设置分片上传数量。
                     int chuckCount = (temData.length % offset == 0) ? temData.length/offset : (1 + temData.length/offset);

                     for (int i = 1; i <= chuckCount; i++) {
                         OSSUploadPartRequest * uploadPart = [OSSUploadPartRequest new];
                         uploadPart.bucketName = XLBucketName;
                         uploadPart.objectkey = fileNamePath;
                         uploadPart.uploadId = uploadId;
                         uploadPart.partNumber = i; // part number start from 1
                         NSFileHandle* readHandle = [NSFileHandle fileHandleForReadingAtPath:newPath];
                         [readHandle seekToFileOffset:offset * (i -1)];
                         NSData* data = [readHandle readDataOfLength:(NSUInteger)offset];
                         uploadPart.uploadPartData = data;
                         OSSTask * uploadPartTask = [self->_client uploadPart:uploadPart];
                         [uploadPartTask waitUntilFinished];
                         if (!uploadPartTask.error) {
                             OSSUploadPartResult * result = uploadPartTask.result;
                             uint64_t fileSize = [[[NSFileManager defaultManager] attributesOfItemAtPath:uploadPart.uploadPartFileURL.absoluteString error:nil] fileSize];
                             [partInfos addObject:[OSSPartInfo partInfoWithPartNum:i eTag:result.eTag size:fileSize crc64:0]];
                         } else {
                             NSLog(@"upload part error: %@", uploadPartTask.error);
                             //移除缓存文件
                             [self isDeleteManageFilesPath:newPath];
                             //回调失败结果
                             dispatch_async(dispatch_get_main_queue(), ^{
                                 failBlock(uploadPartTask.error, XLNetworkReachabilityStatusUnkonw);
                             });
                             return;
                         }
                     }
                     OSSCompleteMultipartUploadRequest * complete = [OSSCompleteMultipartUploadRequest new];
                     complete.bucketName = XLBucketName;
                     complete.objectKey = fileNamePath;
                     complete.uploadId = uploadId;
                     complete.partInfos = partInfos;
                     OSSTask * completeTask = [self->_client completeMultipartUpload:complete];
                     [[completeTask continueWithBlock:^id(OSSTask *task) {
                         if (!task.error) {
                             OSSCompleteMultipartUploadResult * result = task.result;
                             XLLog(@"OSSCompleteMultipartUploadResult %@", result);
                             //移除缓存文件
                             [self isDeleteManageFilesPath:newPath];
                             //回调成功结果
                             dispatch_async(dispatch_get_main_queue(), ^{
                                 successBlock([self fetchSuccessBlockResult:@[complete.objectKey]]);
                             });
                         } else {
                             //移除缓存文件
                             [self isDeleteManageFilesPath:newPath];
                             //回调失败结果
                             dispatch_async(dispatch_get_main_queue(), ^{
                                 failBlock(task.error, XLNetworkReachabilityStatusUnkonw);
                             });
                         }
                         return nil;
                     }] waitUntilFinished];
                });
            }
        }];
    } else {//其他格式视频，采用普通上传方式
        NSData *temData = [NSData dataWithContentsOfURL:pathUrl];
        //文件夹名称
        NSString *filePath = [NSString stringWithFormat:@"%@video",SSOFilePath];
        //文件类型
        NSString *suffixName = @".mp4";//后缀名
        NSString *fileNamePath = [NSString stringWithFormat:@"%@/%@_%d%@",filePath,[XLDateTool getCurrentTimeFormatter:@"yyyyMMddHHmmssSSS"],(arc4random()%10000),suffixName];
        OSSPutObjectRequest *put = [OSSPutObjectRequest new];
        put.bucketName = XLBucketName;
        put.objectKey = fileNamePath;
        put.uploadingData = temData;
        put.uploadProgress = ^(int64_t bytesSent, int64_t totalBytesSent, int64_t totalBytesExpectedToSend) {
            XLLog(@"%lld, %lld, %lld", bytesSent, totalBytesSent, totalBytesExpectedToSend);
        };
        OSSTask *putTask = [self->_client putObject:put];
        [putTask continueWithBlock:^id _Nullable(OSSTask * _Nonnull task) {
            if (!task.error) {
                //删除缓存文件
                successBlock([self fetchSuccessBlockResult:@[put.objectKey]]);
            } else {
                //删除缓存文件
                failBlock(task.error, XLNetworkReachabilityStatusUnkonw);
            }
            return nil;
        }];
        [putTask waitUntilFinished];
    }
}

//删除OSS上传文件
- (void)deleteOssExitFiles:(NSArray *)fileNamePaths
              successBlock:(DeleteDatasSuccessBlock)successBlock
                 failBlock:(DeleteDatasFailBlock)failBlock {
    for (int i = 0; i < fileNamePaths.count; i++) {
        NSString *fileName = fileNamePaths[i];
        NSError * error = nil;
        BOOL isExist = [_client doesObjectExistInBucket:XLBucketName objectKey:fileName error:&error];
        if (isExist) {
            OSSDeleteObjectRequest * delete = [OSSDeleteObjectRequest new];
            delete.bucketName = XLBucketName;
            delete.objectKey = fileName;

            OSSTask * deleteTask = [_client deleteObject:delete];

            [deleteTask continueWithBlock:^id(OSSTask *task) {
                if (!task.error) {
                    if (i == fileNamePaths.count -1) {//表示删除成功
                        successBlock([self fetchDeleteBlockResult:YES]);
                    } else {
                        failBlock(task.error);
                    }
                } else {
                    failBlock(task.error);
                }
                return nil;
            }];
            [deleteTask waitUntilFinished];
        }
    }

}

#pragma mark - Private
//压缩视频
-(void)compressVideoAccroding:(NSURL *)originFilePath successBlock:(void(^)(NSString *newPath))successBlock {
    NSData *originData = [NSData dataWithContentsOfURL:originFilePath];
    XLLog(@"源文件大小%fM", originData.length/(1024*1024.0));
    NSString *outPath = [NSTemporaryDirectory() stringByAppendingPathComponent:[NSString stringWithFormat:@"tem%@", [XLDateTool getCurrentTimeFormatter:@"yyyyMMddHHmmSSS"]]];
    AVURLAsset *asset = [AVURLAsset URLAssetWithURL:originFilePath options:nil];

    AVAssetExportSession *exportSession= [[AVAssetExportSession alloc] initWithAsset:asset presetName:AVAssetExportPresetMediumQuality];
    exportSession.shouldOptimizeForNetworkUse = YES;
    exportSession.outputURL = [NSURL fileURLWithPath:outPath];
    
    NSArray *supportedTypeArray = exportSession.supportedFileTypes;
    if ([supportedTypeArray containsObject:AVFileTypeMPEG4]) {
        exportSession.outputFileType = AVFileTypeMPEG4;
    } else if (supportedTypeArray.count == 0) {
        successBlock(nil);
        return;
    } else {
        exportSession.outputFileType = [supportedTypeArray objectAtIndex:0];
    }
    
    AVMutableVideoComposition *videoComposition = [self fixedCompositionWithAsset:asset];
    if (videoComposition.renderSize.width) {
        //修正视频转向
        exportSession.videoComposition = videoComposition;
    }
    [exportSession exportAsynchronouslyWithCompletionHandler:^{
        int exportStatus = (int)exportSession.status;
        NSLog(@"转码状态:%d",exportStatus);
        if (exportStatus == AVAssetExportSessionStatusCompleted) {
            NSURL *url = [NSURL fileURLWithPath:outPath];
            NSData *videoData = [NSData dataWithContentsOfURL:url];
            XLLog(@"压缩文件的路径%@", outPath);
            XLLog(@"压缩之后文件大小%fM", videoData.length/(1024*1024.0));
            //删除导出临时文件
            NSError *error = nil;
            BOOL isDelete = [[NSFileManager defaultManager] removeItemAtPath:outPath error:&error];
            if (isDelete) {
                XLLog(@"临时文件删除成功");
            }
            NSString *savePath = [NSTemporaryDirectory() stringByAppendingPathComponent:[NSString stringWithFormat:@"temVideo%@", [XLDateTool getCurrentTimeFormatter:@"yyyyMMddHHmmSSS"]]];

            BOOL isSuccess = [self creatFileSaveData:savePath datas:videoData];
            if (isSuccess) {
                if (videoData.length > XLFilesUploadSize) {
                    successBlock(nil);
                } else {
                    successBlock(savePath);
                }
            } else {
                successBlock(nil);
            }
        } else {
            successBlock(nil);
        }
    }];
}

//存储文件到fileManger
- (BOOL)creatFileSaveData:(NSString *)path datas:(NSData *)datas {
    BOOL isFile = [[NSFileManager defaultManager] createFileAtPath:path contents:datas attributes:nil];
    if (isFile) {
        XLLog(@"创建文件成功");
    } else {
        XLLog(@"创建文件失败");
    }
    return isFile;
}

- (BOOL)isDeleteManageFilesPath:(NSString *)filesPath {
    BOOL isSuccess = NO;
    NSError *error;
    NSFileManager *fileManager = [NSFileManager defaultManager];
    isSuccess = [fileManager removeItemAtPath:filesPath error:&error];
    if (error) {
        NSLog(@"移除文件失败：%@",[error localizedDescription]);
    }else{
        NSLog(@"移除文件成功");
    }
    return isSuccess;
}

- (NSDictionary *)fetchSuccessBlockResult:(NSArray *)contentArr {
    NSMutableDictionary *dict = [[NSMutableDictionary alloc] initWithDictionary:self.ossInfoDic];

    [dict setValue:@(YES) forKey:@"result_code"];
    if (contentArr.count > 0) {
        NSData *jsonData = [NSJSONSerialization dataWithJSONObject:contentArr options:0 error:nil];
        NSString *contentStr = [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding];

        [dict setValue:contentStr forKey:@"content"];
    }
    return dict;
}


- (NSDictionary *)fetchDeleteBlockResult:(BOOL)result {
    NSMutableDictionary *dict = [[NSMutableDictionary alloc] initWithDictionary:self.ossInfoDic];

    [dict setValue:@(result) forKey:@"result_code"];
    return dict;
}


//修正视频转向
/// 获取优化后的视频转向信息
- (AVMutableVideoComposition *)fixedCompositionWithAsset:(AVAsset *)videoAsset {
    AVMutableVideoComposition *videoComposition = [AVMutableVideoComposition videoComposition];
    // 视频转向
    int degrees = [self degressFromVideoFileWithAsset:videoAsset];
    if (degrees != 0) {
        CGAffineTransform translateToCenter;
        CGAffineTransform mixedTransform;
        videoComposition.frameDuration = CMTimeMake(1, 30);
        
        NSArray *tracks = [videoAsset tracksWithMediaType:AVMediaTypeVideo];
        AVAssetTrack *videoTrack = [tracks objectAtIndex:0];
        
        AVMutableVideoCompositionInstruction *roateInstruction = [AVMutableVideoCompositionInstruction videoCompositionInstruction];
        roateInstruction.timeRange = CMTimeRangeMake(kCMTimeZero, [videoAsset duration]);
        AVMutableVideoCompositionLayerInstruction *roateLayerInstruction = [AVMutableVideoCompositionLayerInstruction videoCompositionLayerInstructionWithAssetTrack:videoTrack];
        
        if (degrees == 90) {
            // 顺时针旋转90°
            translateToCenter = CGAffineTransformMakeTranslation(videoTrack.naturalSize.height, 0.0);
            mixedTransform = CGAffineTransformRotate(translateToCenter,M_PI_2);
            videoComposition.renderSize = CGSizeMake(videoTrack.naturalSize.height,videoTrack.naturalSize.width);
            [roateLayerInstruction setTransform:mixedTransform atTime:kCMTimeZero];
        } else if(degrees == 180){
            // 顺时针旋转180°
            translateToCenter = CGAffineTransformMakeTranslation(videoTrack.naturalSize.width, videoTrack.naturalSize.height);
            mixedTransform = CGAffineTransformRotate(translateToCenter,M_PI);
            videoComposition.renderSize = CGSizeMake(videoTrack.naturalSize.width,videoTrack.naturalSize.height);
            [roateLayerInstruction setTransform:mixedTransform atTime:kCMTimeZero];
        } else if(degrees == 270){
            // 顺时针旋转270°
            translateToCenter = CGAffineTransformMakeTranslation(0.0, videoTrack.naturalSize.width);
            mixedTransform = CGAffineTransformRotate(translateToCenter,M_PI_2*3.0);
            videoComposition.renderSize = CGSizeMake(videoTrack.naturalSize.height,videoTrack.naturalSize.width);
            [roateLayerInstruction setTransform:mixedTransform atTime:kCMTimeZero];
        }
        
        roateInstruction.layerInstructions = @[roateLayerInstruction];
        // 加入视频方向信息
        videoComposition.instructions = @[roateInstruction];
    }
    return videoComposition;
}

/// 获取视频角度
- (int)degressFromVideoFileWithAsset:(AVAsset *)asset {
    int degress = 0;
    NSArray *tracks = [asset tracksWithMediaType:AVMediaTypeVideo];
    if([tracks count] > 0) {
        AVAssetTrack *videoTrack = [tracks objectAtIndex:0];
        CGAffineTransform t = videoTrack.preferredTransform;
        if(t.a == 0 && t.b == 1.0 && t.c == -1.0 && t.d == 0){
            // Portrait
            degress = 90;
        } else if(t.a == 0 && t.b == -1.0 && t.c == 1.0 && t.d == 0){
            // PortraitUpsideDown
            degress = 270;
        } else if(t.a == 1.0 && t.b == 0 && t.c == 0 && t.d == 1.0){
            // LandscapeRight
            degress = 0;
        } else if(t.a == -1.0 && t.b == 0 && t.c == 0 && t.d == -1.0){
            // LandscapeLeft
            degress = 180;
        }
    }
    return degress;
}

@end
